package util;

import pojo.PoolConnection;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;


public class DataSource {
    private static String url = null;
    private static String password = null;
    private static String rootname = null;
    private static Integer initialPoolSize = 0;
    private static Integer maxPoolSize = 0;
    private static Integer checkoutTimeout = 0;
    private static List<PoolConnection> connections = new ArrayList<>();

    //    static {
//        String url = "jdbc:mysql://localhost:3306/itcast";
//        String rootname = "root";
//        String password = "296924";
//        Integer initialPoolSize=5;
//        Integer maxPoolSize=10;
//        Integer checkoutTimeout=3000;
//    }
    static {
        Properties dataPro = new Properties();
        InputStream inputStream = DataSource.class.getResourceAsStream("/property/dataSource.properties");
        try {
            dataPro.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        rootname = dataPro.getProperty("rootname");
        password = dataPro.getProperty("password");
        url = dataPro.getProperty("url");
        initialPoolSize = Integer.valueOf(dataPro.getProperty("initialPoolSize"));
        maxPoolSize = Integer.valueOf(dataPro.getProperty("maxPoolSize"));
        checkoutTimeout = Integer.valueOf(dataPro.getProperty("checkoutTimeout"));
    }

    //配置文件读取
    public static Properties getProperties() {
        Properties dataPro = new Properties();
        InputStream inputStream = DataSource.class.getResourceAsStream("/property/dataSource.properties");
        try {
            dataPro.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return dataPro;
    }

    //初始化连接集合
    public static void initialConnections() {
        for (int i = 0; i < initialPoolSize; i++) {
            Connection connection;
            try {
                connection = DataSource.creatEachConnection();
                PoolConnection poolConnection = new PoolConnection();
                poolConnection.setConnection(connection);
                poolConnection.setState(0);
                connections.add(poolConnection);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    //初始化连接集合，应该初始化datasouce
    public DataSource() {
//        this.rootname = DataSource.getProperties().getProperty("rootname");
//        this.password = DataSource.getProperties().getProperty("password");
//        this.url = DataSource.getProperties().getProperty("url");
//        this.initialPoolSize = Integer.valueOf(DataSource.getProperties().getProperty("initialPoolSize"));
//        this.maxPoolSize = Integer.valueOf(DataSource.getProperties().getProperty("maxPoolSize"));
//        this.checkoutTimeout = Integer.valueOf(DataSource.getProperties().getProperty("checkoutTimeout"));
//        for (int i = 0; i < initialPoolSize; i++) {
//            Connection connection = null;
//            try {
//                connection = DataSource.creatEachConnection();
//                PoolConnection poolConnection = new PoolConnection();
//                poolConnection.setConnection(connection);
//                poolConnection.setState(0);
//                connections.add(poolConnection);
//            } catch (SQLException e) {
//                e.printStackTrace();
//            }
//        }
        DataSource.initialConnections();
    }


    public static void changeState(PoolConnection connection) {
        for (PoolConnection poolConnection : connections) {
            if (poolConnection.equals(connection)) {
                poolConnection.setState(1);
                //connections.remove(poolConnection);
            }
        }
    }

    //在原本的集合中查找有无空闲的连接
    public static PoolConnection getDataSourceConnection() throws SQLException {
        for (PoolConnection connection : connections) {
            if (connection.getState() == 0) {
                Connection connection1 = connection.getConnection();
                connection.setState(1);
                changeState(connection);
                return connection;
            }
        }
        PoolConnection poolConnection = creatConnection();
        if (poolConnection != null) return poolConnection;
        else return null;
    }

    /**
     * 集合已有连接数
     *
     * @return
     */
    public static Integer connected() {
        Integer number = connections.size();
        return number;
    }


    //public static PoolConnection getConnection() throws SQLException {
//        PoolConnection poolConnection=new PoolConnection();
//        if(connections==null){
//            initialConnections();
//        }
//        poolConnection=getDataSourceConnection();
//        if(poolConnection==null&&connected()<maxPoolSize){
//            //创建新的连接
//            creatConnection();
//            //重新找寻闲置的连接
//            poolConnection=getDataSourceConnection();
//            if(poolConnection==null){
//                System.out.println("nonono");
//            }
//        }
//        return poolConnection;
    //}


    //获取一个连接
    public static Connection getConnection() {
        PoolConnection poolConnection = new PoolConnection();
        if (connections == null) {
            initialConnections();
        }
        try {
            poolConnection = getDataSourceConnection();
            if (poolConnection == null && connected() < maxPoolSize) {
                //创建新的连接
                creatConnection();
                //重新找寻闲置的连接
                try {
                    poolConnection = getDataSourceConnection();
                } catch (SQLException e) {
                    throw new Exception("已没有连接");
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            if (poolConnection == null) {
                throw new Exception("已达到连接池最大连接数");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return poolConnection.getConnection();
    }

    //创造一个连接
    public static Connection creatEachConnection() throws SQLException {
        Connection connection = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");

            connection = DriverManager.getConnection(url, rootname, password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }

    //重新加载，创造新的连接并放进集合
    public static PoolConnection creatConnection() throws SQLException {
        PoolConnection poolConnection = new PoolConnection();
        if (connected() < maxPoolSize) {
            Connection connection = DriverManager.getConnection(url, rootname, password);
            //poolConnection.setConnection(connection);
            poolConnection = new PoolConnection(connection, 1);
            connections.add(poolConnection);
            return poolConnection;
        } else return null;

    }

    //资源释放
    public static void free(Connection connection) {
        for (PoolConnection poolConnection : connections) {
            if (poolConnection.getConnection().equals(connection)) {
                poolConnection.setState(0);
            }
        }
    }


    public static Integer getInitialPoolSize() {
        return initialPoolSize;
    }

    public static Integer getMaxPoolSize() {
        return maxPoolSize;
    }


//    public DataSource() {
//    }
//
//    public DataSource(Integer initialPoolSize, Integer maxPoolSize, Integer checkoutTimeout, ArrayList<Connection> connections){
//        this.initialPoolSize = initialPoolSize;
//        this.maxPoolSize = maxPoolSize;
//        this.checkoutTimeout = checkoutTimeout;
//        //this.connections = connections;
//    }

//    @Override
//    public String toString() {
//        return "DataSource{" +
//                "initialPoolSize=" + initialPoolSize +
//                ", maxPoolSize=" + maxPoolSize +
//                ", checkoutTimeout=" + checkoutTimeout +
//                ", connections=" + connections +
//                '}';
//    }

//    @Override
//    public String toString() {
//        return "DataSource{" +
//                "initialPoolSize=" + initialPoolSize +
//                ", maxPoolSize=" + maxPoolSize +
//                ", checkoutTimeout=" + checkoutTimeout +
//                '}';
//    }
}
